# +----------------------------------------------------------------------
# | ChatWork
# +----------------------------------------------------------------------
# | 这不是一个自由软件,您只能在不用于商业目的的前提下对程序代码进行修改和使用。
# | 任何企业和个人不允许对程序代码以任何形式任何目的再发布,商业使用请获取授权。
# +----------------------------------------------------------------------
# | Author: ChatWork Team <2474369941@qq.com>
# +----------------------------------------------------------------------
import time
from typing import List
from tortoise.queryset import Q
from pydantic import TypeAdapter
from tortoise.transactions import in_transaction
from exception import AppException
from common.models.agents import AgentRobotModel
from common.models.agents import AgentChatRoomingModel
from common.models.agents import AgentChatSessionModel
from common.models.agents import AgentChatRecordsModel
from apps.api.schemas.agent.chat import session_schema as schema


class ChatSessionService:
    """ 会话服务类 """

    @classmethod
    async def lists(cls, params: schema.ChatSessionSearchIn, user_id: int) -> List[schema.ChatSessionListVo]:
        """
        会话列表

        Args:
            params (schema.ChatSessionSearchIn): 会话搜索参数。
            user_id (int): 用户ID。

        Returns:
            List[schema.ChatSessionListVo]: 会话列表Vo。

        Author:
            zero
        """
        where = []
        if params.keyword:
            where.append(Q(name__icontains=params.keyword))

        rooming = await (AgentChatRoomingModel
                         .filter(bot=params.bot)
                         .filter(user_id=user_id)
                         .filter(is_delete=0)
                         .get())

        sessions = (await AgentChatSessionModel
                    .filter(*where)
                    .filter(user_id=user_id)
                    .filter(room_id=rooming.id)
                    .filter(robot_id=rooming.robot_id)
                    .filter(is_delete=0)
                    .order_by("-id")
                    .limit(300)
                    .all().values("id", "name"))

        return [TypeAdapter(schema.ChatSessionListVo).validate_python(item) for item in sessions]

    @classmethod
    async def add(cls, bot: str, name: str, user_id: int):
        """
        会话创建

        Args:
            bot (str): 智能体编号。
            name (str): 会话名称。
            user_id (int): 用户ID。

        Author:
            zero
        """
        robot = await AgentRobotModel.filter(code=bot, is_delete=0).first().values("id")
        if not robot:
            raise AppException("智能体不存在")

        rooming = await AgentChatRoomingModel.filter(robot_id=robot["id"], user_id=user_id, is_delete=0).get()
        if not rooming:
            raise AppException("对话窗口异常")

        name = name[:32] if len(name) > 32 else name
        await AgentChatSessionModel.create(
            user_id=user_id,
            room_id=rooming.id,
            robot_id=robot["id"],
            name=name,
            create_time=int(time.time()),
            update_time=int(time.time())
        )

    @classmethod
    async def edit(cls, id_: int, name: str, user_id: int):
        """
        会话编辑

        Args:
            id_ (int): 会话ID。
            name (str): 会话名称。
            user_id (int): 用户ID。

        Author:
            zero
        """
        session = await AgentChatSessionModel.filter(id=id_).filter(user_id=user_id).first()
        if not session:
            raise AppException("当前会话不存在")

        robot = await AgentRobotModel.filter(id=session.robot_id, is_delete=0).first().values("id")
        if not robot:
            raise AppException("智能体已不存在")

        name = name[:32] if len(name) > 32 else name
        await AgentChatSessionModel.filter(id=id_).update(
            name=name,
            update_time=int(time.time())
        )

    @classmethod
    async def delete(cls, id_: int, user_id: int):
        """
        会话删除

        Args:
            id_ (id): 会话ID。
            user_id (id): 用户ID。

        Author:
            zero
        """
        session = await AgentChatSessionModel.filter(id=id_, user_id=user_id).first()
        if not session:
            raise AppException("当前会话不存在")

        robot = await AgentRobotModel.filter(id=session.robot_id, is_delete=0).first().values("id")
        if not robot:
            raise AppException("智能体已不存在")

        async with in_transaction("mysql"):
            # 删除会话
            await AgentChatSessionModel.filter(id=id_).update(
                is_delete=1,
                delete_time=int(time.time())
            )
            # 删除记录
            await AgentChatRecordsModel.filter(session_id=session.id, is_delete=0).update(
                user_delete=1,
                delete_time=int(time.time())
            )

    @classmethod
    async def clear(cls, bot: str, user_id: int):
        """
        会话清空

        Args:
            bot (str): 智能体编号。
            user_id (id): 用户ID。

        Author:
            zero
        """
        robot = await AgentRobotModel.filter(code=bot, is_delete=0).first().values("id")
        if not robot:
            raise AppException("智能体已不存在")

        sessions = await AgentChatSessionModel.filter(robot_id=robot["id"], user_id=user_id, is_delete=0).values("id")
        session_ids = [item["id"] for item in sessions]
        if session_ids:
            async with in_transaction("mysql"):
                await AgentChatSessionModel.filter(id__in=session_ids, is_delete=0).update(
                    is_delete=1,
                    delete_time=int(time.time())
                )

                await AgentChatRecordsModel.filter(session_id__in=session_ids, is_delete=0).update(
                    is_delete=1,
                    delete_time=int(time.time())
                )
